home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1998 November / Freeware November 1998.img / dist / fw_UDELxntp.idb / usr / freeware / src / xntp-3.4o-export / authstuff / keyparity.c.z / keyparity.c
C/C++ Source or Header  |  1998-01-21  |  5KB  |  280 lines

  1. /*
  2.  * keyparity - add parity bits to key and/or change an ascii key to binary
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <ctype.h>
  8.  
  9. #include "ntp_string.h"
  10. #include "ntp_stdlib.h"
  11.  
  12. #define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  13.  
  14. /*
  15.  * Types of ascii representations for keys.  "Standard" means a 64 bit
  16.  * hex number in NBS format, i.e. with the low order bit of each byte
  17.  * a parity bit.  "NTP" means a 64 bit key in NTP format, with the
  18.  * high order bit of each byte a parity bit.  "Ascii" means a 1-to-8
  19.  * character string whose ascii representation is used as the key.
  20.  */
  21. #define    KEY_TYPE_STD    1
  22. #define    KEY_TYPE_NTP    2
  23. #define    KEY_TYPE_ASCII    3
  24.  
  25. #define    STD_PARITY_BITS    0x01010101
  26.  
  27. char *progname;
  28. int debug;
  29.  
  30. int ntpflag = 0;
  31. int stdflag = 0;
  32. int asciiflag = 0;
  33. int ntpoutflag = 0;
  34. int gotoopt = 0;
  35.  
  36. static    int    parity    P((u_long *));
  37. static    int    decodekey P((int, char *, u_long *));
  38. static    void    output    P((u_long *, int));
  39.  
  40. /*
  41.  * main - parse arguments and handle options
  42.  */
  43. void
  44. main(argc, argv)
  45. int argc;
  46. char *argv[];
  47. {
  48.     int c;
  49.     int errflg = 0;
  50.     int keytype;
  51.     u_long key[2];
  52.     extern int ntp_optind;
  53.     extern char *ntp_optarg;
  54.  
  55.     progname = argv[0];
  56.     while ((c = ntp_getopt(argc, argv, "adno:s")) != EOF)
  57.         switch (c) {
  58.         case 'a':
  59.             asciiflag = 1;
  60.             break;
  61.         case 'd':
  62.             ++debug;
  63.             break;
  64.         case 'n':
  65.             ntpflag = 1;
  66.             break;
  67.         case 's':
  68.             stdflag = 1;
  69.             break;
  70.         case 'o':
  71.             if (*ntp_optarg == 'n') {
  72.                 ntpoutflag = 1;
  73.                 gotoopt = 1;
  74.             } else if (*ntp_optarg == 's') {
  75.                 ntpoutflag = 0;
  76.                 gotoopt = 1;
  77.             } else {
  78.                 (void) fprintf(stderr,
  79.                     "%s: output format must be `n' or `s'\n",
  80.                     progname);
  81.                 errflg++;
  82.             }
  83.             break;
  84.         default:
  85.             errflg++;
  86.             break;
  87.         }
  88.     if (errflg || ntp_optind == argc) {
  89.         (void) fprintf(stderr,
  90.             "usage: %s -n|-s [-a] [-o n|s] key [...]\n",
  91.             progname);
  92.         exit(2);
  93.     }
  94.  
  95.     if (!ntpflag && !stdflag) {
  96.         (void) fprintf(stderr,
  97.             "%s: one of either the -n or -s flags must be specified\n",
  98.             progname);
  99.         exit(2);
  100.     }
  101.  
  102.     if (ntpflag && stdflag) {
  103.         (void) fprintf(stderr,
  104.             "%s: only one of the -n and -s flags may be specified\n",
  105.             progname);
  106.         exit(2);
  107.     }
  108.  
  109.     if (!gotoopt) {
  110.         if (ntpflag)
  111.             ntpoutflag = 1;
  112.     }
  113.  
  114.     if (asciiflag)
  115.         keytype = KEY_TYPE_ASCII;
  116.     else if (ntpflag)
  117.         keytype = KEY_TYPE_NTP;
  118.     else
  119.         keytype = KEY_TYPE_STD;
  120.  
  121.     for (; ntp_optind < argc; ntp_optind++) {
  122.         if (!decodekey(keytype, argv[ntp_optind], key)) {
  123.             (void) fprintf(stderr,
  124.                 "%s: format of key %s invalid\n",
  125.                 progname, argv[ntp_optind]);
  126.             exit(1);
  127.         }
  128.         (void) parity(key);
  129.         output(key, ntpoutflag);
  130.     }
  131.     exit(0);
  132. }
  133.  
  134.  
  135.  
  136. /*
  137.  * parity - set parity on a key/check for odd parity
  138.  */
  139. static int
  140. parity(key)
  141.     u_long *key;
  142. {
  143.     u_long mask;
  144.     int parity_err;
  145.     int bitcount;
  146.     int half;
  147.     int byte;
  148.     int i;
  149.  
  150.     /*
  151.      * Go through counting bits in each byte.  Check to see if
  152.      * each parity bit was set correctly.  If not, note the error
  153.      * and set it right.
  154.      */
  155.     parity_err = 0;
  156.     for (half = 0; half < 2; half++) {        /* two halves of key */
  157.         mask = 0x80000000;
  158.         for (byte = 0; byte < 4; byte++) {    /* 4 bytes per half */
  159.             bitcount = 0;
  160.             for (i = 0; i < 7; i++) {    /* 7 data bits / byte */
  161.                 if (key[half] & mask)
  162.                     bitcount++;
  163.                 mask >>= 1;
  164.             }
  165.  
  166.             /*
  167.              * If bitcount is even, parity must be set.  If
  168.              * bitcount is odd, parity must be clear.
  169.              */
  170.             if ((bitcount & 0x1) == 0) {
  171.                 if (!(key[half] & mask)) {
  172.                     parity_err++;
  173.                     key[half] |= mask;
  174.                 }
  175.             } else {
  176.                 if (key[half] & mask) {
  177.                     parity_err++;
  178.                     key[half] &= ~mask;
  179.                 }
  180.             }
  181.             mask >>= 1;
  182.         }
  183.     }
  184.  
  185.     /*
  186.      * Return the result of the parity check.
  187.      */
  188.     return (parity_err == 0);
  189. }
  190.  
  191.  
  192. static int
  193. decodekey(keytype, str, key)
  194.     int keytype;
  195.     char *str;
  196.     u_long *key;
  197. {
  198.     u_char keybytes[8];
  199.     char *cp;
  200.     char *xdigit;
  201.     int len;
  202.     int i;
  203.     static char *hex = "0123456789abcdef";
  204.  
  205.     cp = str;
  206.     len = strlen(cp);
  207.     if (len == 0)
  208.         return 0;
  209.  
  210.     switch(keytype) {
  211.     case KEY_TYPE_STD:
  212.     case KEY_TYPE_NTP:
  213.         if (len != 16)        /* Lazy.  Should define constant */
  214.             return 0;
  215.         /*
  216.          * Decode hex key.
  217.          */
  218.         key[0] = 0;
  219.         key[1] = 0;
  220.         for (i = 0; i < 16; i++) {
  221.             if (!isascii(*cp))
  222.                 return 0;
  223.             xdigit = strchr(hex, isupper(*cp) ? tolower(*cp) : *cp);
  224.             cp++;
  225.             if (xdigit == 0)
  226.                 return 0;
  227.             key[i>>3] <<= 4;
  228.             key[i>>3] |= (u_long)(xdigit - hex) & 0xf;
  229.         }
  230.  
  231.         /*
  232.          * If this is an NTP format key, put it into NBS format
  233.          */
  234.         if (keytype == KEY_TYPE_NTP) {
  235.             for (i = 0; i < 2; i++)
  236.                 key[i] = ((key[i] << 1) & ~STD_PARITY_BITS)
  237.                     | ((key[i] >> 7) & STD_PARITY_BITS);
  238.         }
  239.         break;
  240.     
  241.     case KEY_TYPE_ASCII:
  242.         /*
  243.          * Make up key from ascii representation
  244.          */
  245.         memset(keybytes, 0, sizeof(keybytes));
  246.         for (i = 0; i < 8 && i < len; i++)
  247.             keybytes[i] = *cp++ << 1;
  248.         key[0] = keybytes[0] << 24 | keybytes[1] << 16
  249.             | keybytes[2] << 8 | keybytes[3];
  250.         key[1] = keybytes[4] << 24 | keybytes[5] << 16
  251.             | keybytes[6] << 8 | keybytes[7];
  252.         break;
  253.     
  254.     default:
  255.         /* Oh, well */
  256.         return 0;
  257.     }
  258.  
  259.     return 1;
  260. }
  261.  
  262.  
  263. /*
  264.  * output - print a hex key on the standard output
  265.  */
  266. static void
  267. output(key, ntpformat)
  268.     u_long *key;
  269.     int ntpformat;
  270. {
  271.     int i;
  272.  
  273.     if (ntpformat) {
  274.         for (i = 0; i < 2; i++)
  275.             key[i] = ((key[i] & ~STD_PARITY_BITS) >> 1)
  276.                 | ((key[i] & STD_PARITY_BITS) << 7);
  277.     }
  278.     (void) printf("%08x%08x\n", key[0], key[1]);
  279. }
  280.